package com.zhongan.gateway.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import redis.clients.jedis.Jedis;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.zhongan.gateway.bean.Developer;
import com.zhongan.gateway.bean.DeveloperIp;
import com.zhongan.gateway.common.constant.GwDeveloperApiConstant;
import com.zhongan.gateway.mapper.DeveloperIpMapper;
import com.zhongan.gateway.mapper.DeveloperMapper;
import com.zhongan.gateway.service.DeveloperService;
import com.zhongan.gateway.service.RedisService;
import com.zhongan.gateway.web.common.PageDTO;

@Component
public class DeveloperServiceImpl implements DeveloperService {

    private static final Logger logger = LoggerFactory.getLogger(DeveloperServiceImpl.class);
    @Resource
    private DeveloperMapper     developerMapper;
    @Resource
    private DeveloperIpMapper   developerIpMapper;

    @Resource
    private RedisService        redisService;

    @Override
    public int deleteDeveloperById(Long id, String appkey) {
        String key = GwDeveloperApiConstant.GW_CACHE_DEV + appkey;
        redisService.clearCacheByKey(key);
        logger.info("start deleteDeveloperById,id= {},appkey={}", id, appkey);
        int i = developerMapper.deleteByPrimaryKey(id);
        logger.info("end deleteDeveloperById,i={}", i);

        return i;
    }

    @Override
    public String insertDeveloper(Developer record) {
        logger.info("start insertDeveloper, {}", record.toString());
        record.setAppKey(UUID.randomUUID().toString());
        int i = developerMapper.insert(record);
        logger.info("end insertDeveloper,i={}", i);

        return record.getAppKey();
    }

    @Override
    public int updateDeveloper(Developer record) {
        String key = GwDeveloperApiConstant.GW_CACHE_DEV + record.getAppKey();
        redisService.clearCacheByKey(key);
        logger.info("start updateDeveloper, {}", record.toString());
        int i = developerMapper.updateByPrimaryKey(record);
        logger.info("end updateDeveloper,i={}", i);

        return i;
    }

    @Override
    public Developer selectDeveloperById(Long id) {
        Developer dev = developerMapper.selectByPrimaryKey(id);
        return dev;
    }

    @Override
    public Developer selectDeveloperByAppKey(String appKey) {
        Developer dev = null;
        String key = GwDeveloperApiConstant.GW_CACHE_DEV + appKey;
        Jedis jedis = redisService.getJedis();
        String result = redisService.get(jedis, key);

        if (!StringUtils.isEmpty(result)) {
            dev = JSONObject.parseObject(result, Developer.class);
        } else {
            Developer record = new Developer();
            record.setAppKey(appKey);
            List<Developer> list = developerMapper.selectByParams(record);
            if (null != list && list.size() != 1) {
                logger.warn("selectDeveloperByAppKey error,appkey={} ,result size={}", appKey, list.size());

            } else {
                dev = list.get(0);
                redisService.set(jedis, key, JSONObject.toJSONString(dev));
            }
        }
        redisService.closeJedis(jedis);
        return dev;
    }

    @Override
    public List<Developer> selectDevelopers(Developer record) {

        List<Developer> list = developerMapper.selectByParams(record);
        return list;
    }

    @Override
    public int deleteIpById(Long id, Long developerId) {
        String key = GwDeveloperApiConstant.GW_CACHE_DEVIP + developerId;
        redisService.clearCacheByKey(key);
        logger.info("start deleteIpById, id={},developerId={}", id, developerId);
        int i = developerIpMapper.deleteByPrimaryKey(id);
        logger.info("end deleteIpById,i={}", i);

        return i;
    }

    @Override
    public PageDTO<Developer> selectPageDevelopers(String appKey, String devName, Integer start, Integer limit) {
        Map<String, Object> map = new HashMap<String, Object>();
        if (!StringUtils.isEmpty(appKey)) {
            map.put("appKey", appKey);
        }
        if (!StringUtils.isEmpty(devName)) {
            map.put("devName", devName);
        }

        int count = developerMapper.countByParams(map);
        map.put("start", start);
        map.put("limit", limit);
        List<Developer> apis = developerMapper.selectPageByParams(map);
        PageDTO<Developer> page = new PageDTO<Developer>();
        page.setStart(start);
        page.setLimit(limit);
        page.setRows(apis);
        page.setResults(count);
        page.setHasError(false);
        return page;
    }

    @Override
    public int insertIp(DeveloperIp record) {
        String key = GwDeveloperApiConstant.GW_CACHE_DEVIP + record.getDeveloperId();
        redisService.clearCacheByKey(key);
        logger.info("start insertIp, {}", record.toString());
        int i = developerIpMapper.insert(record);
        logger.info("end insertIp,i={}", i);

        return i;
    }

    @Override
    public DeveloperIp selectIpById(Long id) {
        DeveloperIp ip = developerIpMapper.selectByPrimaryKey(id);
        return ip;
    }

    @Override
    public List<DeveloperIp> selectIps(Long developerId) {
        String key = GwDeveloperApiConstant.GW_CACHE_DEVIP + developerId;
        Jedis jedis = redisService.getJedis();
        String result = redisService.get(jedis, key);
        List<DeveloperIp> list = null;
        if (result != null) {
            if (!"".equals(result)) {
                list = (List<DeveloperIp>) JSONObject.parseObject(result, new TypeReference<List<DeveloperIp>>() {
                });
            }
        } else {
            list = developerIpMapper.selectByDeveloperId(developerId);
            if (null != list && !list.isEmpty()) {
                redisService.set(jedis, key, JSONObject.toJSONString(list));
            } else {
                redisService.set(jedis, key, "");
            }
        }
        redisService.closeJedis(jedis);
        return list;
    }
}
